﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

namespace Utils.Tool.ReadFile
{
    public class ConfigFileOperation
    {
        private static ConfigFileOperation m_operation = new ConfigFileOperation();

        private Dictionary<string, string> configCache = new Dictionary<string, string>();


        public ConfigFileOperation()
        {
#if UNITY_EDITOR
            string configDir = Path.Combine(Application.dataPath, "GameMain/RunimeConfigs");
#else
            string configDir = Path.Combine(Application.persistentDataPath, "Config");
#endif
            string filePath = Path.Combine(configDir, "config.txt");

            // 2. 确保目录存在
            if (!Directory.Exists(configDir))
            {
                Directory.CreateDirectory(configDir);
                return;
            }

            if (File.Exists(filePath))
            {
                foreach (string line in File.ReadAllLines(filePath))
                {
                    if (string.IsNullOrWhiteSpace(line) || line.StartsWith("##"))
                        continue;

                    string[] parts = line.Split('=');
                    if (parts.Length == 2)
                    {
                        configCache[parts[0].Trim()] = parts[1].Trim();
                    }
                }
            }
        }


        public static bool TryGetBool(string key, out bool rs)
        { 
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
            {
                rs = false;
                return false;
            }
            rs = int.Parse(valueStr) == 1 ? true : false;
            return true;
        }

        public static bool GetBool(string key, bool defaultValue)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
                return defaultValue;
            return int.Parse(valueStr) == 1 ? true : false;
        }


        public static bool TryGetInt(string key, out int rs)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
            {
                rs = 0;
                return false;
            }
            rs = int.Parse(valueStr);
            return true;
        }

        public static int GetInt(string key, int defaultValue)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
                return defaultValue;
            return int.Parse(valueStr);
        }


        public static bool TryGetFloat(string key, out float rs)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
            {
                rs = 0f;
                return false;
            }
            rs = float.Parse(valueStr);
            return true;
        }


        public static float GetFloat(string key, float defaultValue)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
                return defaultValue;
            return float.Parse(valueStr);
        }



        public static bool TryGetString(string key, out string rs)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
            {
                rs = null;
                return false;
            }
            rs = valueStr;
            return true;
        }

        public static string GetString(string key, string defaultValue)
        {
            string valueStr = null;
            if (!m_operation.configCache.TryGetValue(key, out valueStr))
                return defaultValue;
            return valueStr;
        }


        public static void SetBool(string propKey, bool propValue)
        {
            m_operation.configCache[propKey] = propValue ? "1" : "0";
        }

        public static void SetInt(string propKey, int propValue)
        {
            m_operation.configCache[propKey] = propValue.ToString();
        }


        public static void SetFloat(string propKey, float propValue)
        {
            m_operation.configCache[propKey] = propValue.ToString();
        }

        public static void SetString(string propKey, string propValue)
        {
            m_operation.configCache[propKey] = propValue;
        }



        public static void Save()
        {
#if UNITY_EDITOR
            string configDir = Path.Combine(Application.dataPath, "GameMain/RunimeConfigs");
#else
            string configDir = Path.Combine(Application.persistentDataPath, "Config");
#endif
            string filePath = Path.Combine(configDir, "config.txt");

            // 2. 确保目录存在
            if (!Directory.Exists(configDir))
            {
                Directory.CreateDirectory(configDir);
                return;
            }

            File.WriteAllLines(
                filePath,
                m_operation.configCache.Select(kvp => $"{kvp.Key} = {kvp.Value}"));
        }



        public static void WriteConfig(string propKey, string propValue)
        {
            try
            {
                // 1. 配置目录和文件路径
#if UNITY_EDITOR
                string configDir = Path.Combine(Application.dataPath, "GameMain/RunimeConfigs");
#else
                string configDir = Path.Combine(Application.persistentDataPath, "Config");
#endif
                string filePath = Path.Combine(configDir, "config.txt");

                // 2. 确保目录存在
                if (!Directory.Exists(configDir))
                {
                    Directory.CreateDirectory(configDir);
                }

                // 3. 读取现有配置（如果文件存在）
                Dictionary<string, string> config = new Dictionary<string, string>();
                if (File.Exists(filePath))
                {
                    foreach (string line in File.ReadAllLines(filePath))
                    {
                        if (string.IsNullOrWhiteSpace(line) || line.StartsWith("##"))
                            continue;

                        string[] parts = line.Split('=');
                        if (parts.Length == 2)
                        {
                            config[parts[0].Trim()] = parts[1].Trim();
                        }
                    }
                }

                // 4. 更新或添加目标属性
                config[propKey] = propValue;

                // 5. 将配置写回文件
                var lines = config.Select(kvp => $"{kvp.Key} = {kvp.Value}");

                // 跨平台可靠写入（.NET 5+）
                //  使用FileMode.Create，而非FileMode.OpenOrCreate. 因为可能覆盖不完全。
                {
                    using var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096,
                        FileOptions.WriteThrough);
                    using var sw = new StreamWriter(fs);
                    sw.Write(string.Join(Environment.NewLine, lines));
                    sw.Flush();
                    fs.Flush(true);
                }

                //  .NET 6+
                //  所属库和命名空间
                //  库: .NET Runtime（System.Runtime 或 System.Private.CoreLib）
                //  命名空间: System.IO
                
                // File.WriteAllLines(
                //     filePath,
                //     lines,
                //     new FileStreamOptions 
                //     {
                //         Mode = FileMode.Create,
                //         Options = FileOptions.WriteThrough
                //     }
                // );
                
#if UNITY_EDITOR

                string file = Application.dataPath + "/Resources/Config/Config.txt";
                Dictionary<string, string> config_ = new Dictionary<string, string>();
                if (!File.Exists(file))
                {
                    File.Create(file).Close();
                }
                else
                {
                    var allLines = File.ReadAllLines(file);

                    if (allLines?.Length > 0)
                    {
                        // var lines_ = textAsset.text.Split("\n");

                        foreach (string line in allLines)
                        {
                            if (string.IsNullOrWhiteSpace(line) || line.StartsWith("##"))
                                continue;

                            string[] parts = line.Split('=');
                            if (parts.Length == 2)
                            {
                                config_[parts[0].Trim()] = parts[1].Trim();
                            }
                        }
                    }
                }
                
                // //  避免下次读取时，读取的是缓存
                // Resources.UnloadAsset(textAsset);
                config_[propKey] = propValue;
                    
                var newlines = config_.Select(kvp => $"{kvp.Key} = {kvp.Value}");
                
                // File.WriteAllLines(
                //     Application.dataPath + "/Resources/Config/Config.txt",
                //     newlines);
                using var fs_ = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough);
                using var sw_ = new StreamWriter(fs_);
                sw_.Write(string.Join(Environment.NewLine, newlines));
                sw_.Flush();
                fs_.Flush(true);
#endif
                
                
                
            }
            catch (Exception ex)
            {
                Debug.LogError($"写入配置文件失败: {ex.Message}");
            }
            
            
        }
        
        
        public static string ReadConfig(string propKey, string defaultValue = "")
        {
#if UNITY_EDITOR
            string configDir = Path.Combine(Application.dataPath, "Config");
#else
                string configDir = Path.Combine(Application.persistentDataPath, "Config");
#endif
            string filePath = Path.Combine(configDir, "config.txt");
            if (File.Exists(filePath))
            {
                string[] lines = File.ReadAllLines(filePath);
                Dictionary<string, string> config = new Dictionary<string, string>();

                foreach (string line in lines)
                {
                    if (string.IsNullOrEmpty(line) || line.StartsWith("##"))
                    {
                        continue;
                    }

                    string[] parts = line.Split('=');
                    if (parts.Length == 2)
                    {
                        string key = parts[0].Trim();
                        string value = parts[1].Trim();
                        config[key] = value;
                    }
                }

                if (config.ContainsKey(propKey))
                {
                    string numberStr = config[propKey];
                    
                    return numberStr;
                }

            }

            var textAsset = Resources.Load<TextAsset>("Config/Config");
            if(textAsset == null)
                return defaultValue;
            var lines_ = textAsset.text.Split("\n");
            Dictionary<string, string> config_ = new Dictionary<string, string>();

            foreach (string line in lines_)
            {
                if (string.IsNullOrEmpty(line) || line.StartsWith("##"))
                {
                    continue;
                }

                string[] parts = line.Split('=');
                if (parts.Length == 2)
                {
                    string key = parts[0].Trim();
                    string value = parts[1].Trim();
                    config_[key] = value;
                }
            }

            if (config_.ContainsKey(propKey))
            {
                string numberStr = config_[propKey];
                    
                return numberStr;
            }
            else
            {
                return defaultValue;
            }
        }
    } 
}
